package com.onpositive.units;

import java.util.HashMap;
import java.util.LinkedHashSet;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.onpositive.data.units.Unit;
import com.onpositive.data.units.Units;

public class ParsedProperty {
	
	private HashMap<String, ParsedProperty> children ;
//	IStringPoolProvider stringPoolProvider ;

	public ParsedProperty(String propName) {
		this.name = propName;
	}
	public ParsedProperty(String propName, boolean isService ) {
		this.name = propName;
		this.isService = isService ;
	}	

	private String name;
	private boolean isService = false ;


	public LinkedHashSet<ParsedValue> values = new LinkedHashSet<ParsedValue>();

	public void write(Element element ) {
		for (ParsedValue val : values) {
			
			
			Element newElement = element.getOwnerDocument().createElement("property");
			newElement.setAttribute("name", name.trim() );
			element.appendChild(newElement);
			val.writeValue(newElement);
		}
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void addValue( ParsedValue value )
	{		
		if (value==null){
			return ; //throw new IllegalArgumentException();
		}
		if( value instanceof ParsedDimension )
		{
			ParsedDimension newParsedDim = (ParsedDimension) value ;
			addParsedDimension( newParsedDim );
			return ;
		}		
		values.add( value ) ;
	}
	
	private	void addParsedDimension(ParsedDimension value )
	{
		Unit unit = value.getUnit() ;
		if( unit == null )
		{
			values.add( value ) ;
			return ;			
		}
		
		Unit[] congruentUnits = Units.getCongruentUnits(unit) ;
		if( congruentUnits == null )
		{
			values.add( value ) ;
			return ;			
		}
					
		for( ParsedValue pv : values )
		{
			if( !(pv instanceof ParsedDimension) )
				continue ;
					
			ParsedDimension pd = (ParsedDimension) pv ;
			if( pd.isDetailed() )
				continue ;
			
			Unit oldUnit = pd.getUnit() ;
			if( oldUnit.getKind() == unit.getKind()
					&& !oldUnit.equals(unit)
					&& Units.areCongruent(oldUnit, unit) )
			{
				Unit baseUnit = congruentUnits[0] ;
				values.remove(pd) ;
				ParsedDimension finalVal = ParsedDimension.appendValue( value, pd, baseUnit, this ) ;
				values.add(finalVal) ;
				return ;
			}			
		}
		values.add( value ) ;
	}	
	
	public boolean removeValue( ParsedValue value )
	{		
		if ( value==null || values == null )
			return false ;
		
		return values.remove( value ) ;
	}
	
	public LinkedHashSet<ParsedValue> getValues()
	{
		return values ;
	}
	public String getValueAsText()
	{
		String result = "" ;
		if( values != null && values.size() > 0 )
		{
			ParsedValue[] v = new ParsedValue[ values.size() ];
			try{
			values.toArray(v) ;
			result += v[0].getValueAsString() ;
			}catch(Exception e){
				return "" ;
			}
			
			for( int i = 1 ; i < v.length ; i++ )
				result += ( "; "+v[i].getValueAsString() ) ;			
		}
		return result;
	}
//	public void setValueAsText( String s )
//	{
//		setValue( s );		
//	}
//	public void setValue( String s )
//	{
//		String propName = getName() ;
//		this.values.clear() ;
//		String[] rawValues = s.split(";") ;		
//		for( String propValue : rawValues )
//		{
//			String[] preprocessed = CompositeValueParser.preprocess(propName, propValue) ;
//			if( preprocessed != null && preprocessed.length > 1 
//									 && preprocessed[0] != null && preprocessed[1] != null )
//			{							
//				propName  = preprocessed[0] ;
//				propValue = preprocessed[1] ;
//			}
//			
//			ParsedValue value = CompositeValueParser.parse( propName.trim(), propValue.trim());
//			values.add( value ) ;
//		}
//	}

	public HashMap<String, ParsedProperty> getChildren() {
		return children;
	}
	
	public void setChild( String propertyName , ParsedProperty prop )
	{
		if( children == null )
			children = new HashMap<String, ParsedProperty>() ;
		
		children.put(propertyName, prop) ;
	}
	public boolean isService() {
		return isService;
	}

//	public IStringPoolProvider getStringPoolProvider() {
//		return stringPoolProvider;
//	}
//
//	public void setStringPoolProvider(IStringPoolProvider stringPoolProvider) {
//		this.stringPoolProvider = stringPoolProvider;
//	}
}
